/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Rutas;
import com.thoughtworks.xstream.XStream;
import java.io.FileReader;
import java.io.IOException;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Usuario
 */
public class TabuFiorella {
    private List<Ruta> listaRutas;//la lista completa de rutas
    private int numRutas; //numero total de rutas
    private int numRecorridos=49; //por ahora son estaticos, total 50
    private int longTramos=5; //TAMANO DEL TRAMO
    private List<Integer> tramoElegido;//lista de tramos ya tomados
    private List<Integer> rutaElegido;//lista de rutas ya tomados
    
    public TabuFiorella(int num){//el numero de rutas
        this.numRutas = num;
    }
    
    public void leerRutasOriginales() {
       Ruta ruta;
       List<Ruta> lista;
       lista = new ArrayList<Ruta>();
       for(int i=1;i<=this.numRutas;i++){
            String nombre ="Ruta"+i+"/RutaOriginal.xml";
            try {
                ruta = new Ruta();
                XStream xs = new XStream();
                FileReader fr = new FileReader(nombre);
                ruta= (Ruta)xs.fromXML(fr);
                lista.add(ruta);//agrega la ruta ideal leida
                fr.close();
            } 
            catch (IOException e) {
                System.out.println(e.toString());
            }
       }
       this.listaRutas = lista;
    }
    
    public Ruta leerRutaRecorrida (int rutaIdeal, int rutaRec) {
       Ruta ruta= new Ruta();
       int i = rutaIdeal;
       int j = rutaRec;
       String nombre ="Ruta"+i+"/RutaRecorrida"+j+".xml";
       try {
           XStream xs = new XStream();
           FileReader fr = new FileReader(nombre);
           ruta= (Ruta)xs.fromXML(fr);
           fr.close();
        } catch (IOException e) {
           System.out.println(e.toString());
	}
       return ruta;
    }
    
    public int compruebaNuevoRecorrido(int j){
        //devuelve 1 si el recorrido es nuevo
        //devuelve 0 si ya fue elegido antes
        if(this.rutaElegido.size()==0){//si esta vacio
            this.rutaElegido.add(j);
            return 1;
        }
        //si ya se tiene alguna ruta en la lista
        for(int i=0; i<this.rutaElegido.size();i++){
            int aux = this.rutaElegido.get(i);
            if(j==aux){
                //si entra es xq ya ha sido considerado antes en la comparacion
                return 0;
            }
        }
        this.rutaElegido.add(j);
        return 1;
    }
    
    public int compruebaNuevoTramo(int j){
        //devuelve 1 si el recorrido es nuevo
        //devuelve 0 si ya fue elegido antes
        if(this.tramoElegido.size()==0){//si esta vacio
            this.tramoElegido.add(j);
            return 1;
        }
        //si ya se tiene alguna ruta en la lista
        for(int i=0; i<this.tramoElegido.size();i++){
            int aux = this.tramoElegido.get(i);
            if(j==aux){
                //si entra es xq ya ha sido considerado antes en la comparacion
                return 0;
            }
        }
        this.tramoElegido.add(j);
        return 1;
    }
    
    public List<Paradero> leeTramo(Ruta recorrido, int tramo){
        List<Paradero> aux = new ArrayList<Paradero>();
        for(int i=0; i<this.longTramos; i++){
            aux.add(recorrido.getListaParaderos().get(tramo + i));
        }
        return aux;
    }
    
    public void imprimeTramo(List<Paradero> r){
        for(int i=0; i<r.size();i++)
            System.out.print(r.get(i).getIdParadero());
        System.out.println();
    }
    
    public void algoritmo(){
        int numBus;
        int numTramos;
        double percTramos = 0.2;
        numBus = Math.round((float)(this.numRecorridos*0.2));
        Ruta rutaRecorrida;
        List<Paradero> tramoRec;//el tramo recorrido
        List<Paradero> tramoIdeal;//el tramo ideal
        //este es el numero de rutas recorridas que se van a considerar, el 20%
  //for (int m=0; m<30;m++){      
        long ini= System.currentTimeMillis();
        //primero se lee todas las rutas ideales
        leerRutasOriginales();//ESTA BIEN!!!!
        //con esto se llena el atributo listaRutas
        for(int i=0;i<this.numRutas;i++){            
            //try {
                //solo se lee el 20% de los tramos
                //System.out.println();
                //System.out.println("RUTA " + (i+1));
                Random r = new Random();
                for(int j=1;j<=numBus;j++){
                    int incEncontradas = 0;
                    int incEncontradasBLAST = 0;
                    //solo se lee el 20% de los tramos
                    this.rutaElegido = new ArrayList<Integer>();
                    //esta lista se reinicia para cada ruta
                    int aux = 1;
                    int recorrido = 0;
                    while(aux==1){
                        recorrido = (int)(r.nextInt(this.numRecorridos-1))+1; 
                        //ahora debemos comprobar que el recorrido escogido sea nuevo
                        if(compruebaNuevoRecorrido(recorrido)==1)//si es un nuevo tramo
                            aux = 0;
                        //FUNCIONAMIENTO COMPROBADO
                    }
                    //System.out.println();
                    //****System.out.print("RUTA " + (i+1)+"-BUS " + recorrido);
                    //System.out.println();
                    //cuando salga se asegura que se tenga un recorrido nuevo
                    //ahora solo se lee el recorrido del bus seleccionado
                    rutaRecorrida = new Ruta();
                    rutaRecorrida = leerRutaRecorrida(i+1, recorrido);
                    //ahora se selecciona solo un tramo
                    //solo se compara el 20% de los tramos del recorrido
                    numTramos = Math.round((float)(rutaRecorrida.getListaParaderos().size()/this.longTramos))+1;
                    //ESTE ES EL NUMERO MAXIMO DE TRAMOS EN LA RUTA
                    int aux2 =  Math.round((float)(numTramos*percTramos));
                    //SOLO SE VA A UTILIZAR EL 20% DEL TOTAL DE TRAMOS
                    this.tramoElegido = new ArrayList<Integer>();
                    //solo hay 100/long tramo candidatos posibles para tramos
                    /*System.out.println("Tamaño ruta: "+rutaRecorrida.getListaParaderos().size());
                    System.out.println("Tamaño tramos: "+this.longTramos);
                    System.out.println("Division: "+(rutaRecorrida.getListaParaderos().size()/this.longTramos));
                    System.out.println("Candidatos: "+cand);*/
                    NedWun a;
                    BLAST b;
                    for(int k=1; k<=aux2;k++){//ELIGE LOS TRAMOS
                        int auxTramo = 1;
                        int tramo = 0;
                        while(auxTramo==1){
                            tramo = (int)r.nextInt(numTramos); 
                            //ahora debemos comprobar que el recorrido escogido sea nuevo
                            //System.out.println("Considerado: "+tramo);
                            if(compruebaNuevoTramo(tramo)==1)//si es un nuevo tramo
                                auxTramo = 0;
                            //FUNCIONAMIENTO COMPROBADO
                        }
                        //System.out.println("Elegido " + k +": "+tramo*5);
                        //ahora se lee el tramos recorrido
                        tramoRec = new ArrayList<Paradero>();
                        //System.out.print("Tramo Recorrido " + k + ": ");
                        tramoRec = leeTramo(rutaRecorrida,tramo);
                        //imprimeTramo(tramoRec);
                        tramoIdeal = new ArrayList<Paradero>();
                        //System.out.print("Tramo Ideal " + k + ": ");
                        tramoIdeal = leeTramo(this.listaRutas.get(i),tramo);
                        //imprimeTramo(tramoIdeal);
                        //AQUI SE LLAMA A LOS ALGORITMOS
                        
                        a = new NedWun(tramoIdeal, tramoRec);
                        incEncontradas = incEncontradas + a.algoritmo();
                        b = new BLAST();
                        incEncontradasBLAST = incEncontradasBLAST + b.algoritmoObjetos(tramoIdeal, tramoRec);
                    
                
                    }
                    System.out.println("RUTA "+(i+1)+"-BUS "+recorrido+"-NEDWUN-Incidencias Esperadas: " + rutaRecorrida.getNumIncOcurridas()+ "-"
                    + "Incidencias Capturadas: " + incEncontradas);
                    System.out.println("RUTA "+(i+1)+"-BUS "+recorrido+"-BLAST-Incidencias Esperadas: " + rutaRecorrida.getNumIncOcurridas()+ "-"
                    + "Incidencias Capturadas: " + incEncontradasBLAST);
                    
                }
                
                //Thread.sleep(100);
            //} catch (InterruptedException ex) {
              //  Logger.getLogger(TabuFiorella.class.getName()).log(Level.SEVERE, null, ex);
            //}
            //System.out.println();
            //System.out.print("RUTA " + (i+1));
            //System.out.println();
        }
        
            long fin= System.currentTimeMillis();
                System.out.println();
                System.out.println("Tiempo ejecucion: "+(fin-ini));
    }
    //}
}
